package com.quad.innovators.salesease.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.quad.innovators.salesease.cache.SysRoleDataPermissionCache;
import com.quad.innovators.salesease.constants.SecurityConstants;
import com.quad.innovators.salesease.mapper.SysRoleDataPermissionMapper;
import com.quad.innovators.salesease.model.bo.DataPermissionBO;
import com.quad.innovators.salesease.model.entity.SysRoleDataPermission;
import com.quad.innovators.salesease.service.SysRoleDataPermissionService;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
@Slf4j
@RequiredArgsConstructor
public class SysRoleDataPermissionServiceImpl extends ServiceImpl<SysRoleDataPermissionMapper, SysRoleDataPermission> implements SysRoleDataPermissionService {


    private final SysRoleDataPermissionCache sysRoleDataPermissionCache;

    @PostConstruct
    public void initRolePermsCache() {
        log.info("初始化数据权限缓存... ");
        refreshRolePermsCache();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(String roleCode, List<DataPermissionBO> list) {
        // 删除
        this.baseMapper.delete(new LambdaQueryWrapper<SysRoleDataPermission>()
                .eq(SysRoleDataPermission::getRoleCode, roleCode));
        // 新增
        List<SysRoleDataPermission> sysRoleDataPermissionList = list.stream().map(it -> {
            SysRoleDataPermission sysRoleDataPermission = new SysRoleDataPermission();
            sysRoleDataPermission.setRoleCode(roleCode);
            sysRoleDataPermission.setMenuCode(it.getMenuCode());
            sysRoleDataPermission.setDataPermissionCode(it.getDataPermissionCode());
            sysRoleDataPermission.setDataScope(it.getDataPermission());
            return sysRoleDataPermission;
        }).collect(Collectors.toList());
        this.saveBatch(sysRoleDataPermissionList);
    }

    @Override
    public List<DataPermissionBO> selectByRole(String roleCode) {
        List<SysRoleDataPermission> sysRoleDataPermissionList = this.baseMapper.selectList(new LambdaQueryWrapper<SysRoleDataPermission>()
                .eq(SysRoleDataPermission::getRoleCode, roleCode));
        return sysRoleDataPermissionList.stream().map(it -> {
            DataPermissionBO sysRoleDataPermission = new DataPermissionBO();
            sysRoleDataPermission.setMenuCode(it.getMenuCode());
            sysRoleDataPermission.setDataPermissionCode(it.getDataPermissionCode());
            sysRoleDataPermission.setDataPermission(it.getDataScope());
            return sysRoleDataPermission;
        }).collect(Collectors.toList());
    }

    @Override
    public void refreshRolePermsCache() {
        sysRoleDataPermissionCache.clear();
        List<SysRoleDataPermission> sysRoleDataPermissionList = this.baseMapper.selectList(new QueryWrapper<>());
        if(CollectionUtil.isNotEmpty(sysRoleDataPermissionList)){
            Map<String, List<SysRoleDataPermission>> group = sysRoleDataPermissionList.stream().collect(Collectors.groupingBy(SysRoleDataPermission::getRoleCode));
            for (Map.Entry<String, List<SysRoleDataPermission>> entry : group.entrySet()) {
                Map<String, Integer> values = new HashMap<>();
                String roleCode = entry.getKey();
                for (SysRoleDataPermission roleDataPermsBO : entry.getValue()) {
                    values.put(roleDataPermsBO.getDataPermissionCode(), roleDataPermsBO.getDataScope());
                }
                sysRoleDataPermissionCache.set(SecurityConstants.ROLE_DATA_PERMS_PREFIX + roleCode, values);
            }
        }
    }

    @Override
    public void refreshRolePermsCache(String roleCode) {
        sysRoleDataPermissionCache.remove(SecurityConstants.ROLE_DATA_PERMS_PREFIX + roleCode);
        List<SysRoleDataPermission> sysRoleDataPermissionList = this.baseMapper.selectList(new LambdaQueryWrapper<SysRoleDataPermission>()
                .eq(SysRoleDataPermission::getRoleCode, roleCode));
        if(CollectionUtil.isNotEmpty(sysRoleDataPermissionList)){
            Map<String, List<SysRoleDataPermission>> group = sysRoleDataPermissionList.stream().collect(Collectors.groupingBy(SysRoleDataPermission::getRoleCode));
            for (Map.Entry<String, List<SysRoleDataPermission>> entry : group.entrySet()) {
                Map<String, Integer> values = new HashMap<>();
                for (SysRoleDataPermission roleDataPermsBO : entry.getValue()) {
                    values.put(roleDataPermsBO.getDataPermissionCode(), roleDataPermsBO.getDataScope());
                }
                sysRoleDataPermissionCache.set(SecurityConstants.ROLE_DATA_PERMS_PREFIX + roleCode, values);
            }
        }
    }

    @Override
    public void refreshRolePermsCache(String oldRoleCode, String newRoleCode) {
        // 清理旧角色权限缓存
        sysRoleDataPermissionCache.remove(SecurityConstants.ROLE_DATA_PERMS_PREFIX + oldRoleCode);
        // 添加新角色权限缓存
        refreshRolePermsCache(newRoleCode);
    }


}
